package com.kkd.kkdapp.db.base;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import com.kkd.kkdapp.utils.LogUtil;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.text.TextUtils;


public class BaseEASQLiteOpenHelper extends SQLiteOpenHelper {

	public BaseEASQLiteOpenHelper(Context context, String name,
			CursorFactory factory, int version) {
		super(context, name, factory, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}

	/**
	 * 根据条件查找对象并返回第一个
	 * 
	 * @param clazz
	 * @param selection
	 * @return
	 */
	public <T> T queryTopOne(Class<T> clazz, String selection,
			String[] selectionArgs) {
		T t = null;
		Cursor c = null;
		String[] columns = SqlBuilder.getColumns(clazz);
		Field[] fs = EATool.getField(clazz);
		try {
			c = query(clazz.getSimpleName(), columns, selection, selectionArgs,
					null, null, null);
			if (null != c && c.moveToFirst()) {
				t = parseToEntity(clazz, c, fs);
				c.close();
			}
			
		} catch (Exception e) {
			LogUtil.exception(e);
		} finally {
			if (null != c) {
				c.close();
				c = null;
			}
		}
		return t;
	}

	/**
	 * 根据条件查找对象并返回所有
	 * 
	 * @param clazz
	 * @param selection
	 * @return
	 */
	public <T> List<T> queryAll(Class<T> clazz, String selection) {
		Cursor c = null;
		List<T> list = new ArrayList<T>();
		String[] columns = SqlBuilder.getColumns(clazz);
		Field[] fs = EATool.getField(clazz);
		try {
			c = query(clazz.getSimpleName(), columns, selection, null, null,
					null, null);
			if (null != c) {
				for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
					list.add(parseToEntity(clazz, c, fs));
				}
			}
		} catch (Exception e) {
			LogUtil.exception(e);
		} finally {
			if (null != c) {
				c.close();
				c = null;
			}
		}
		return list;
	}

	/**
	 * 根据条件查找对象并返回所有
	 * 
	 * @param clazz
	 * @param selection
	 * @return
	 */
	public <T> List<T> queryAll(Class<T> clazz, String selection,
			String[] selectionArgs, String orderBy, String limit) {
		Cursor c = null;
		List<T> list = new ArrayList<T>();
		String[] columns = SqlBuilder.getColumns(clazz);
		Field[] fs = EATool.getField(clazz);
		try {
			c = query(clazz.getSimpleName(), columns, selection, selectionArgs,
					null, null, orderBy, limit);
			if (null != c) {
				for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
					list.add(parseToEntity(clazz, c, fs));
				}
			}
		} catch (Exception e) {
			LogUtil.exception(e);
		} finally {
			if (null != c) {
				c.close();
				c = null;
			}
		}
		return list;
	}

	/**
	 * 解析成java对象
	 * 
	 * @param clazz
	 * @param c
	 * @param fs
	 * @return
	 */
	private <T> T parseToEntity(Class<T> clazz, Cursor c, Field[] fs) {
		T t = null;
		try {
			t = clazz.newInstance();
			for (int columnIndex = 0, count = c.getColumnCount(); columnIndex < count; columnIndex++) {
				String columnName = c.getColumnName(columnIndex);
				for (int i = 0; i < fs.length; i++) {
					if ("_id".equals(columnName)
							&& "rowid".equals(fs[i].getName())) { // 处理主键
						fs[i].set(t, EATool.getValue(c, fs[i], columnName));
						break;
					} else if (columnName.equals(fs[i].getName())) {
						fs[i].set(t, EATool.getValue(c, fs[i], columnName));
						break;
					}
				}
			}
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return t;
	}

	public Cursor query(String table, String[] columns, String selection,
			String[] selectionArgs, String groupBy, String having,
			String orderBy) {
		return query(table, columns, selection, selectionArgs, groupBy, having,
				orderBy, null);

	}

	public Cursor query(String table, String[] columns, String selection,
			String[] selectionArgs, String groupBy, String having,
			String orderBy, String limit) {
		try {
			return super.getReadableDatabase().query(table, columns, selection,
					selectionArgs, groupBy, having, orderBy, limit);
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return null;
	}

	public int update(String table, ContentValues values, String whereClause,
			String[] whereArgs) {
		try {
			return super.getWritableDatabase().update(table, values,
					whereClause, whereArgs);
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return 0;
	}
	
	public long replace(String table, ContentValues values) {
		try {
			return super.getWritableDatabase().replace(table, null, values);
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return 0;
	}

	public int delete(String table, String whereClause, String[] whereArgs) {
		try {
			return super.getWritableDatabase().delete(table, whereClause,
					whereArgs);
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return 0;
	}

	public void insert(Object entity) {
		execSQL(SqlBuilder.getInsertSql(entity, false));
	}
	
	public void beginTransaction() {
		 super.getWritableDatabase().beginTransaction();
	}
	
	public void endTransaction() {
		super.getWritableDatabase().endTransaction();
	}
	
	public void setTransactionSuccessful() {
		super.getWritableDatabase().setTransactionSuccessful();
	}

	public long saveBindId(Object entity) {
		ContentValues values = SqlBuilder.getContentValuesByObj(entity);
		long i = insert(entity.getClass().getSimpleName(), null, values);
		return i;
	}

	public long insert(String table, String nullColumnHack, ContentValues values) {
		try {
			return super.getWritableDatabase().insert(table, nullColumnHack,
					values);
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return 0;
	}

	public Cursor rawQuery(String sql, String[] selectionArgs) {
		try {
			return super.getReadableDatabase().rawQuery(sql, selectionArgs);
		} catch (Exception e) {
			LogUtil.exception(e);
		}
		return null;
	}
	
	public int queryCount(String table,String selectionSql,String[] selectionArgs){
		StringBuilder query = new StringBuilder("select Count(*) from "+table);
		if(!TextUtils.isEmpty(selectionSql)){
			query.append(" where "+selectionSql);
		}
		
		int count = 0;
		Cursor c = null;
		try {
			c = super.getReadableDatabase().rawQuery(query.toString(), selectionArgs);
			if(c!=null){
				c.moveToFirst();
				count = c.getInt(0);
			}
		} catch (Exception e) {
			LogUtil.exception(e);
		} finally {
			if(c != null) {
				c.close();
			}
		}
		return count;
	}

	public void execSQL(String sql) {
		try {
			super.getWritableDatabase().execSQL(sql);
		} catch (Exception e) {
			LogUtil.exception(e);
		}
	}
	
	@Override
	protected void finalize() throws Throwable {
		this.close();
		super.finalize();
	}
}
